#!/usr/bin/perl
# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
#  
#  
# Licensed Materials - Property of IBM 
#  
# (C) COPYRIGHT International Business Machines Corp. 2000,2002 
# All Rights Reserved 
#  
# US Government Users Restricted Rights - Use, duplication or 
# disclosure restricted by GSA ADP Schedule Contract with IBM Corp. 
#  
# IBM_PROLOG_END_TAG 

#####################################################################
# Subroutines:                                                      #
#                                                                   #
#                                                                   #
#     usage run_cmd getArgs checkPreviousInstallation copyRpm       #
#     copy_csm copy_opensrc_prereqs copy_csmbin copy_distro_rpms    #
#     create_directory_structure install_rpm                        #
#     install_installp_packages isERRMrunning waitForERRM           #
#     install_packages checkrpm                                     #
#                                                                   #
#                                                                   #
#                                                                   #
#####################################################################

use strict;
BEGIN { $::csmpm = $ENV{'CSM_PM'} ? $ENV{'CSM_PM'} : '/opt/csm/pm'; }
use lib $::csmpm;
use File::Path;
# Provides mkpath();
use FindBin qw($Bin);
use lib "$Bin";

use Getopt::Std;
use NodeUtils;
use InstallDefs;
use InstallUtils;

$::MSGCAT = 'csmInstall.cat';
$::MSGMAPPATH = $ENV{'CSM_MSGMAPS'} ? $ENV{'CSM_MSGMAPS'} : '/opt/csm/msgmaps';
$::MSGSET = 'csminstall';

$::MNTCDROM             = "/mnt/cdrom";
@::COPY_VALID_ATTRS=("InstallCSMVersion","InstallOSName","InstallDistributionName","InstallDistributionVersion","InstallPkgArchitecture");
@::osTypeVersion;
$::PLTFRM = `uname`;
chomp ($::PLTFRM);


sub usage
{
NodeUtils->message('I', 'IMsgcopycsmpkgsUsage');

exit 1;
}

sub getArgs
{
    my $pkgpath = "";
    if (! getopts('p:vVh') ) { &usage; }

    if ($::opt_h) { &usage }
    if ($::opt_v || $::opt_V)
    {
        if ($::opt_v) { $::VERBOSE = $::opt_v; }
        if ($::opt_V) { $::VERBOSE = $::opt_V; }

    }
    if ($::opt_p)
    {
        # Packages path
        $pkgpath = $::opt_p;
    }

    if (!($::opt_p)) { &usage; }

    # Handle attr=value arguments
    if (scalar(@ARGV) > 0)
    {
        foreach my $a (@ARGV)
        {
            # Note:  we allow a null value
            my ($attr, $value) = $a =~ /^\s*(\S+?)\s*=\s*(\S*.*)$/;
            #print "ATTR = $attr, VALUE = $value\n";

            # mkrsrc-api needs something for the value
            if (!length($value))
            {
                $value = "''";
            }

            if (!defined($attr))
            {
                NodeUtils->message('W', 'EMsgBAD_ATTR_VAL_FORM');
                &usage;
            }
            my $found = 0;
            foreach my $va (@::COPY_VALID_ATTRS)
            {
                if ($attr eq $va)
                {
                    # Put quotes around the value to protect spaces
                    # or weird chars
                    #$::ATTRS{$va} = NodeUtils->quote($value);
                    $::ATTRS{$va} = $value;
                    #print "ASSIGNED ATTR $va = VALUE $::ATTRS{$va}\n";
                    $found = 1;
                }
            }
            if (!$found)
            {
                NodeUtils->message('E1', 'EMsgBAD_ATTR', $attr);
            }
        }
    }
    &checkattrs();

    @::PKGPATH  = split(":", $pkgpath);
    foreach my $p (split(":", $pkgpath)){  #gather the subdirectories too
    	    push @::PKGPATH, (InstallUtils->returnSubdirectory($p));
    }

}

sub checkattrs
{
   #check if all the attributes are there, if not defined then get the 
   #default from Management Server
   if ( !($::ATTRS{'InstallOSName'}))
   {
       $::ATTRS{'InstallOSName'}=InstallUtils->get_OSName;
   } 
   if ( !($::ATTRS{'InstallCSMVersion'}))
   {
       $::ATTRS{'InstallCSMVersion'}=InstallUtils->get_CSMVersion("csm\.core"); 
   } 
   if ( !($::ATTRS{'InstallDistributionName'}))
   {
       if ( ($::ATTRS{'InstallOSName'} eq "Linux") && ($::PLTFRM eq "Linux") )
       {
         $::ATTRS{'InstallDistributionName'}=InstallUtils->get_DistributionName;
       }
       elsif ( ($::ATTRS{'InstallOSName'} eq "Linux") && ($::PLTFRM eq "AIX") )
       {
          NodeUtils->message('E1', 'EMsgNoDistributionName');
       }
   } 
   if ( !($::ATTRS{'InstallDistributionVersion'}))
   {
       if (  (($::ATTRS{'InstallOSName'} eq "Linux") && ($::PLTFRM eq "Linux")) || (($::ATTRS{'InstallOSName'} eq "AIX") && ($::PLTFRM eq "AIX")) )
       {
          $::ATTRS{'InstallDistributionVersion'}=InstallUtils->get_DistributionVersion; 
       }
       else
       {
          NodeUtils->message('E1', 'EMsgNoDistributionVersion');
       }
   } 
   if ( !($::ATTRS{'InstallPkgArchitecture'}))
   {
       if ( ($::ATTRS{'InstallOSName'} eq "Linux") && ($::PLTFRM eq "Linux") )
       {
          $::ATTRS{'InstallPkgArchitecture'}=InstallUtils->get_PkgArchitecture; 
       }
       elsif ( ($::ATTRS{'InstallOSName'} eq "Linux") && ($::PLTFRM eq "AIX"))
       {
          NodeUtils->message('E1', 'EMsgNoArch');
       }
   } 
   
   # check for the valid attributes
   if (length($::ATTRS{'InstallCSMVersion'})==0)
   {
     NodeUtils->message('E2', 'EMsgNO_CORE_COPY');
   }

   if ($::ATTRS{'InstallOSName'} eq "Linux") 
   {
      if ($::ATTRS{'InstallPkgArchitecture'} =~ /i?86/)
      {
          $::ATTRS{'InstallPkgArchitecture'}="i386";
      }
      my $temp_distro = $::ATTRS{'InstallDistributionName'}. " " .$::ATTRS{'InstallDistributionVersion'};
      if (!grep(/^$temp_distro$/, @::VALID_DISTROS))
      {
          NodeUtils->message('E5', 'EMsgUNSUPPORTED_DISTRO', $temp_distro, join(', ',@::VALID_DISTROS));
      }
      else { NodeUtils->message('V', 'IMsgDETECTED_DISTRO', $temp_distro); }
      if (!grep(/^$::ATTRS{'InstallCSMVersion'}$/,@::VALID_CSM_DISTROS))
      {
          NodeUtils->message('E5', 'EMsgUNSUPPORTED_CSM_DISTRO', "CSM".$::ATTRS{'InstallCSMVersion'}, join(', ',@::VALID_CSM_DISTROS));
      }
      else { NodeUtils->message('V', 'IMsgDETECTED_CSM_DISTRO', "CSM".$::ATTRS{'InstallCSMVersion'}); }

      $::DISTRO = $temp_distro;
   }
   elsif ($::ATTRS{'InstallOSName'} eq "AIX")
   {
      my $temp_distro = $::ATTRS{'InstallOSName'}.$::ATTRS{'InstallDistributionVersion'};
      if (!grep(/^$temp_distro$/,@::VALID_AIX_DISTROS))
      {
            NodeUtils->message('E5', 'EMsgUNSUPPORTED_AIX_DISTRO', $temp_distro, join(', ',@::VALID_AIX_DISTROS));
      }
      else { NodeUtils->message('V', 'IMsgDETECTED_AIX_DISTRO', $temp_distro); }
      if (!grep(/^$::ATTRS{'InstallCSMVersion'}$/,@::VALID_CSM_DISTROS))
      {
            NodeUtils->message('E5', 'EMsgUNSUPPORTED_CSM_DISTRO', "CSM".$::ATTRS{'InstallCSMVersion'}, join(', ',@::VALID_CSM_DISTROS));
      }
      else { NodeUtils->message('V', 'IMsgDETECTED_CSM_DISTRO', "CSM".$::ATTRS{'InstallCSMVersion'}); }
   }
   else
   {
     NodeUtils->message("E2", 'EMsgINVALID_OSTYPE');
   }
   
}

sub getPackageList
{
   if ($::ATTRS{'InstallOSName'} eq "AIX") 
   {
      $::osTypeVersion =  $::ATTRS{'InstallOSName'}.$::ATTRS{'InstallDistributionVersion'};
      $::INSTALLDIR           ="/csminstall";
      $::INSTALLDIR_CSM       =$::INSTALLDIR."/csm";                                  #/csminstall/csm
      $::INSTALLDIR_CSMVR     =$::INSTALLDIR_CSM."/".$::ATTRS{'InstallCSMVersion'}; #/csminstall/csm/1.2/
      $::INSTALLDIR_CSMVRBIN  =$::INSTALLDIR_CSMVR."/bin";                                 #/csminstall/csm/1.2/bin

      $::INSTALLDIR_OS        =$::INSTALLDIR."/".$::ATTRS{'InstallOSName'};           #/csminstall/AIX
      $::INSTALLDIR_OSVER     =$::INSTALLDIR_OS."/".$::ATTRS{InstallDistributionVersion};        #/csminstall/AIX/5.1
      $::INSTALLDIR_OSCSM     =$::INSTALLDIR_OS."/csm";                               #/csminstall/AIX/csm

      $::INSTALLDIR_CSMVER    =$::INSTALLDIR_OSCSM."/".$::ATTRS{'InstallCSMVersion'}; #/csminstall/AIX/csm/1.2.0

      $::INSTALLDIR_CSMBIN    =$::INSTALLDIR_CSMVER."/bin"; #/csminstall/AIX/csm/1.2.0/bin
      $::INSTALLDIR_CSMPKG    =$::INSTALLDIR_CSMVER."/packages"; #/csminstall/AIX/csm/1.2.0/packages
      $::INSTALLDIR_CSMRPM    =$::INSTALLDIR_CSMPKG."/rpms"; #/csminstall/AIX/csm/1.2.0/packages/rpms
      $::INSTALLDIR_CSMINSTLP =$::INSTALLDIR_CSMPKG."/installp"; #/csminstall/AIX/csm/1.2.0/packages/installp
    
      # Lists of Open Source Packages that are required by each CSM component
      #@::server_open_srcrpms =(@{$::opensrc_prereqs{'csm.server'}{$::osTypeVersion}{$::ATTRS{'InstallCSMVersion'}}});
      @::client_open_srcrpms =(@{$::opensrc_prereqs{'csm.client'}{$::osTypeVersion}{$::ATTRS{'InstallCSMVersion'}}});
      @::core_open_srcrpms =(@{$::opensrc_prereqs{'csm.core'}{$::osTypeVersion}{$::ATTRS{'InstallCSMVersion'}}});
      @::opensrc_rpm_prereqs =(@::core_open_srcrpms, @::client_open_srcrpms);

      # Lists of packages that are part of each CSM component
      #@::csm_server_packages =(@{$::csm_packages{'MgmtSvr'}{$::osTypeVersion}{$::ATTRS{'InstallCSMVersion'}}});
      @::csm_client_packages =(@{$::csm_packages{'MgdNode'}{$::osTypeVersion}{$::ATTRS{'InstallCSMVersion'}}});
      @::csm_packages =(@::csm_client_packages);
      @::csm_packages =InstallUtils->get_uniqu_arry_elemnts(@::csm_packages);
      #@::rsct_server_packages =(@{$::rsct_packages{'MgmtSvr'}{$::osTypeVersion}{$::ATTRS{'InstallCSMVersion'}}});
      @::rsct_client_packages =(@{$::rsct_packages{'MgdNode'}{$::osTypeVersion}{$::ATTRS{'InstallCSMVersion'}}});
      @::rsct_packages =(@::rsct_client_packages);
      @::rsct_packages =InstallUtils->get_uniqu_arry_elemnts(@::rsct_packages);

      # Operating System Prereqs
      @::os_prereq =(@{$::Linux_os_prereqs{$::osTypeVersion}});

      # Files that need to be extracted from the the packages
      @::csmbin_core =(@{$::csmbin{'csm.core'}{$::osTypeVersion}{$::ATTRS{'InstallCSMVersion'}}});
      @::csmbin_server =(@{$::csmbin{'csm.server'}{$::osTypeVersion}{$::ATTRS{'InstallCSMVersion'}}});
      @::csmbin_opensrc =(@{$::csmbin{'opensrc'}{$::osTypeVersion}{$::ATTRS{'InstallCSMVersion'}}});
   }
   elsif ($::ATTRS{'InstallOSName'} eq "Linux")
   {
      $::osTypeVersion =  $::ATTRS{'InstallOSName'}.$::ATTRS{'InstallDistributionName'}.$::ATTRS{'InstallDistributionVersion'};
      $::INSTALLDIR           ="/csminstall";
      $::INSTALLDIR_CSM       =$::INSTALLDIR."/csm";                                  #/csminstall/csm
      $::INSTALLDIR_CSMVR     =$::INSTALLDIR_CSM."/".$::ATTRS{InstallCSMVersion}; #/csminstall/csm/1.2/
      $::INSTALLDIR_CSMVRBIN  =$::INSTALLDIR_CSMVR."/bin";                                 #/csminstall/csm/1.2/bin

      $::INSTALLDIR_OS        =$::INSTALLDIR."/".$::ATTRS{"InstallOSName"}."/".$::ATTRS{'InstallDistributionName'};
                                                                                        #/csminstall/Linux/RedHat
      $::INSTALLDIR_OSVER     =$::INSTALLDIR_OS."/".$::ATTRS{InstallDistributionVersion};  #/csminstall/Linux/RedHat/7.0
      $::INSTALLDIR_OSVER_ARCH=$::INSTALLDIR_OSVER."/".$::ATTRS{'InstallPkgArchitecture'}; #/csminstall/Linux/Redhat/7.0/i386

      $::INSTALLDIR_OSCSM     =$::INSTALLDIR_OS."/csm";                               #/csminstall/Linux/RedHat/csm
      $::INSTALLDIR_CSMVER    =$::INSTALLDIR_OSCSM."/".$::ATTRS{InstallCSMVersion}; #/csminstall/Linux/RedHat/csm/1.2.0


      $::INSTALLDIR_OS_NAME  =$::INSTALLDIR_OSVER_ARCH."/".$::ATTRS{InstallDistributionName}; #/csminstall/Linux/Redhat/7.0/i386/RedHat

      $::INSTALLDIR_OS_NAME_RPMS  =$::INSTALLDIR_OS_NAME."/RPMS"; #/csminstall/Linux/Redhat/7.0/i386/RedHat/RPMS
      $::SMS_RPMS = $::INSTALLDIR_OSVER_ARCH."/RPMS"; #/csminstall/Linux/Redhat/7.0/i386/RPMS
      $::SMS_UPDATES = $::INSTALLDIR_OSVER_ARCH."/updates"; #/csminstall/Linux/Redhat/7.0/i386/updates
      #$::INSTALLDIR_OS_NAME_UPDATES  =$::INSTALLDIR_OS_NAME."/updates"; #/csminstall/Linux/Redhat/7.0/i386/RedHat/updates
      $::INSTALLDIR_CSMBIN    =$::INSTALLDIR_CSMVER."/bin"; #/csminstall/Linux/RedHat/csm/1.2.0/bin
      $::INSTALLDIR_CSMPKG    =$::INSTALLDIR_CSMVER."/packages"; #/csminstall/Linux/RedHat/csm/1.2.0/packages

      # Lists of Open Source Packages that are required by each CSM component
      #@::server_open_srcrpms =(@{$::opensrc_prereqs{'csm.server'}{$::osTypeVersion}{$::ATTRS{'InstallCSMVersion'}}});
      @::client_open_srcrpms =(@{$::opensrc_prereqs{'csm.client'}{$::osTypeVersion}{$::ATTRS{'InstallCSMVersion'}}});
      @::core_open_srcrpms =(@{$::opensrc_prereqs{'csm.core'}{$::osTypeVersion}{$::ATTRS{'InstallCSMVersion'}}});
      @::director_open_srcrpms =(@{$::opensrc_prereqs{'csm.director.agent'}{$::osTypeVersion}{$::ATTRS{'InstallCSMVersion'}}});
      @::opensrc_rpm_prereqs =(@::core_open_srcrpms, @::client_open_srcrpms, @::director_open_srcrpms);

      # Lists of packages that are part of each CSM component
      #@::csm_server_packages =(@{$::csm_packages{'MgmtSvr'}{$::osTypeVersion}{$::ATTRS{'InstallCSMVersion'}}});
      @::csm_client_packages =(@{$::csm_packages{'MgdNode'}{$::osTypeVersion}{$::ATTRS{'InstallCSMVersion'}}});
      @::csm_packages =(@::csm_client_packages);
      @::csm_packages =InstallUtils->get_uniqu_arry_elemnts(@::csm_packages);
      #@::rsct_server_packages =(@{$::rsct_packages{'MgmtSvr'}{$::osTypeVersion}{$::ATTRS{'InstallCSMVersion'}}});
      @::rsct_client_packages =(@{$::rsct_packages{'MgdNode'}{$::osTypeVersion}{$::ATTRS{'InstallCSMVersion'}}});
      @::rsct_packages =(@::rsct_client_packages);
      @::rsct_packages =InstallUtils->get_uniqu_arry_elemnts(@::rsct_packages);
      @::director_packages =(@{$::director_packages{'MgdNode'}{$::osTypeVersion}{$::ATTRS{'InstallCSMVersion'}}});

      # Operating System Prereqs
      @::os_prereq =(@{$::Linux_os_prereqs{$::osTypeVersion}});

      # Files that need to be extracted from the the packages
      @::csmbin_core =(@{$::csmbin{'csm.core'}{$::osTypeVersion}{$::ATTRS{'InstallCSMVersion'}}});
      @::csmbin_server =(@{$::csmbin{'csm.server'}{$::osTypeVersion}{$::ATTRS{'InstallCSMVersion'}}});
      @::csmbin_opensrc =(@{$::csmbin{'opensrc'}{$::osTypeVersion}{$::ATTRS{'InstallCSMVersion'}}});
   }
   else
   {
     NodeUtils->message("E2", 'EMsgINVALID_OSTYPE');
   }
}

sub create_directory_structure
{
   mkpath ($::INSTALLDIR_CSMVRBIN, $::VERBOSE, 0755);
   mkpath ($::INSTALLDIR_CSMBIN, $::VERBOSE, 0755);
   if ($::ATTRS{'InstallOSName'} eq "AIX")
   {
      mkpath ($::INSTALLDIR_CSMRPM, $::VERBOSE, 0755);
      mkpath ($::INSTALLDIR_CSMINSTLP, $::VERBOSE, 0755);
   }
   elsif ($::ATTRS{'InstallOSName'} eq "Linux")
   {
      mkpath ($::INSTALLDIR_CSMPKG, $::VERBOSE, 0755);
      mkpath ($::INSTALLDIR_OS_NAME_RPMS, $::VERBOSE, 0755);
      #mkpath ($::INSTALLDIR_OS_NAME_UPDATES, $::VERBOSE, 0755);
      #make updates and RPMS directories
      mkpath ($::SMS_UPDATES, $::VERBOSE, 0755);
      #we made need to add different symbolic links for SUSE, etc.
      if($::PREREQS_ATTR{'DistributionName'} eq "RedHat"){
	       #this is a symbolic link to ->RedHat/RPMS
	       if(!(-e "$::SMS_RPMS")){
			my $ln_cmd = "$::LN -s $::INSTALLDIR_OS_NAME_RPMS $::SMS_RPMS";
			&run_cmd($ln_cmd, "W", "show_all");
       }
      }
      else{ 
		mkpath ($::SMS_RPMS, $::VERBOSE, 0755);
      }

   }
   else
   {
        NodeUtils->message('E2', 'EMsgINVALID_OSTYPE');
   }
}
 
sub run_cmd
{
    my ($cmd, $msgtype, $runtype) = @_;
    my ($rc, @cmdout, $msgtypestr);

    $msgtype = "E" if (!$msgtype);
    $runtype = "show_errors" if (!$runtype);

    NodeUtils->message('V','IMsgCMD',$cmd);
    if ($runtype eq "show_all")
    {
        $rc = system("$cmd") >> 8;
        if ($rc)
        {
            # Only exit with a return code if msgtype = "E" (Error)
            $msgtypestr = $msgtype;
            $msgtypestr = "$msgtype$rc" if ($msgtype eq "E");
            NodeUtils->message("$msgtypestr", 'EMsgCMD_FAILED_RC', $cmd, $rc);
        }
    }
    elsif ($runtype eq "show_errors")
    {
        @cmdout = `$cmd 2>&1`;
        chomp (@cmdout); # take the newline off
        $rc = $? >> 8;

        if ($rc)
        {
            # Only exit with a return code if msgtype = "E" (Error)
            $msgtypestr = $msgtype;
            $msgtypestr = "$msgtype$rc" if ($msgtype eq "E");

            NodeUtils->message("$msgtypestr",'EMsgCMD_FAILED',$cmd,join('', @cmdout));
        }
    }
    elsif ($runtype eq "ignore_errors")
    {
        $rc = system("$cmd") >> 8;
    }
    else
    {
        NodeUtils->message('E1','EMsgRUN_CMD_INVALID', $runtype);
    }

    return $rc;
}

sub copyRpm
{
    my ($rpmfile, $path, $destination) = @_;
    NodeUtils->message("I", 'IMsgCOPYING', $rpmfile);

    mkpath ($destination, $::VERBOSE, 0755);

    &run_cmd("$::COPY $path/$rpmfile $destination");
    &run_cmd("$::CHMOD +r $destination/$rpmfile");
    #If there are any errors during the copy or chmod, run_cmd() exits.
}

sub copy_csm 
{
 if ($::ATTRS{'InstallOSName'} eq "Linux")
 {
    my ($rpmfile, $rpm, $path);
    NodeUtils->message("I", 'IMsgCOPYING_RPMS');
    # Copy RPMs from CSM distribution CD-ROM or directory to dirctory structure
    foreach $rpm (@::csm_packages, @::rsct_packages, @::director_packages)
    {
          if ($::ATTRS{'InstallPkgArchitecture'} =~ /i?86/)
          {
            $rpmfile = "${rpm}-*.i?86.rpm";
            $path = InstallUtils->findRpmInPath($rpmfile, @::PKGPATH);
          }
          else
          {
            $rpmfile = "${rpm}-*.ia64.rpm";
            $path = InstallUtils->findRpmInPath($rpmfile, @::PKGPATH);
            if (!($path))
            {
              $rpmfile = "${rpm}-*.i?86.rpm";
              $path = InstallUtils->findRpmInPath($rpmfile, @::PKGPATH);
            }
          }
          if (!($path))
          {
             $rpmfile = "${rpm}-*.noarch.rpm";
             $path = InstallUtils->findRpmInPath($rpmfile, @::PKGPATH);
          }

          if (defined($path))
          {
              # Get the latest version of the file in the first location found
              if ($::PLTFRM eq "Linux")
              {
                 #my $rpmfile = NodeUtils->runcmd("$::LS -vr $path/${rpm}-* | $::HEAD -1", -1);
                 $rpmfile = InstallUtils->getRecentVersionRpm($path, $rpmfile);
              }
              else
              {
                 #my $rpmfile = NodeUtils->runcmd("$::LS $path/${rpm}-* | $::HEAD -1", -1);
                 $rpmfile = InstallUtils->getRecentVersionRpm($path, $rpmfile);
              }
              chomp $rpmfile;
              my $rpmfile_basename;
              ($rpmfile_basename = $rpmfile) =~ s:^.*/::g;

              &copyRpm($rpmfile_basename, $path, $::INSTALLDIR_CSMPKG);
          }
          else
          {
              NodeUtils->message('E1', 'EMsgCANT_FIND', $rpm, join(':',@::PKGPATH));
          }
    }
 }
 elsif ($::ATTRS{'InstallOSName'} eq "AIX")
 {
    NodeUtils->message("I", 'IMsgCOPYING_INSTALLP');
    # Copy RPMs from CSM distribution CD-ROM or directory to dirctory structure
    foreach my $rpm (@::csm_packages)
    {
          my $rpmfile = "${rpm}";
          my $path = InstallUtils->findRpmInPath($rpmfile, @::PKGPATH);

          if (defined($path))
          {
              # Get the latest version of the file in the first location found
              my $rpmfile = NodeUtils->runcmd("$::LS $path/$rpmfile | $::HEAD -1", -1);
              chomp $rpmfile;
              my $rpmfile_basename;
              ($rpmfile_basename = $rpmfile) =~ s:^.*/::g;

              &copyRpm($rpmfile_basename, $path, $::INSTALLDIR_CSMINSTLP);
          }
          else
          {
              NodeUtils->message('E1', 'EMsgCANT_FIND', $rpmfile, join(':',@::PKGPATH));
          }
    }
    `inutoc $::INSTALLDIR_CSMINSTLP`;
 }
 else
 {
     NodeUtils->message('E2', 'EMsgINVALID_OSTYPE');
 }
}

sub copy_opensrc_prereqs
{
    NodeUtils->message('I', 'IMsgCOPYING_OPENSRC_PREREQS');

    # Append /reqs to each PKGPATH element to search for tarballs
    my (@reqs_PKGPATH) = @::PKGPATH;
    map {s/$/\/reqs/} @reqs_PKGPATH;
  if ($::ATTRS{'InstallOSName'} eq "Linux")
  {
    my ($rpm_pre_file, $rpm_pre, $path);
    # Copy open source prereqs from CSM distribution CD-ROM or directory structure
    foreach $rpm_pre (@::opensrc_rpm_prereqs)
    {
      # check for the i*86 rpm in path and path/reqs....
      if ($::ATTRS{'InstallPkgArchitecture'} =~ /i?86/)
      {
         $rpm_pre_file = "${rpm_pre}-*.i?86.rpm";
         $path = InstallUtils->findRpmInPath($rpm_pre_file, @::PKGPATH);
      }
      else
      {
         $rpm_pre_file = "${rpm_pre}-*.ia64.rpm";
         $path = InstallUtils->findRpmInPath($rpm_pre_file, @::PKGPATH);
         if (!($path))
         {
            $rpm_pre_file = "${rpm_pre}-*.i?86.rpm";
            $path = InstallUtils->findRpmInPath($rpm_pre_file, @::PKGPATH);
         }
      }
      if (!($path))
      {
        $path = InstallUtils->findRpmInPath($rpm_pre_file, @reqs_PKGPATH);
      }
      #...If i*86 not found in path then check for the noarch rpm ....
      if (!($path))
      {
          $rpm_pre_file = "${rpm_pre}-*.noarch.rpm";
          $path = InstallUtils->findRpmInPath($rpm_pre_file, @::PKGPATH);
      }
      if (!($path))
      {
        $path = InstallUtils->findRpmInPath($rpm_pre_file, @reqs_PKGPATH);
      }
      # And finally exit if the rpm is not found else copy
      if (defined($path))
      {
          # Get the latest version of the file in the first location found
          if ($::PLTFRM eq "Linux")
          {
             #my $rpm_pre_file = NodeUtils->runcmd("$::LS -vr $path/$rpm_pre_file | $::HEAD -1", -1);
             $rpm_pre_file = InstallUtils->getRecentVersionRpm($path, $rpm_pre_file);
          }
          else
          {
             #my $rpm_pre_file = NodeUtils->runcmd("$::LS $path/$rpm_pre_file | $::HEAD -1", -1);
             $rpm_pre_file = InstallUtils->getRecentVersionRpm($path, $rpm_pre_file);
          }
          chomp $rpm_pre_file;
          my $rpmfile_basename;
          ($rpmfile_basename = $rpm_pre_file) =~ s:^.*/::g;

          &copyRpm($rpmfile_basename, $path, $::INSTALLDIR_CSMPKG);
       }
       else
       {
            NodeUtils->message('E1', 'EMsgCANT_FIND', $rpm_pre, join(':',@::PKGPATH));
       }

    }
  }
  elsif ($::ATTRS{'InstallOSName'} eq "AIX")
  {
    # Copy open source prereqs from CSM distribution CD-ROM or directory structure
    foreach my $rpm_pre (@::opensrc_rpm_prereqs)
    {
      # check for the i*86 rpm in path and path/reqs....
      my $rpm_pre_file = "${rpm_pre}-*.ppc.rpm";
      my $path = InstallUtils->findRpmInPath($rpm_pre_file, @::PKGPATH);
      if (!($path))
      {
        $path = InstallUtils->findRpmInPath($rpm_pre_file, @reqs_PKGPATH);
      }
      #...If i*86 not found in path then check for the noarch rpm ....
      if (!($path))
      {
          $rpm_pre_file = "${rpm_pre}-*.noarch.rpm";
          $path = InstallUtils->findRpmInPath($rpm_pre_file, @::PKGPATH);
      }
      if (!($path))
      {
        $path = InstallUtils->findRpmInPath($rpm_pre_file, @reqs_PKGPATH);
      }
      # And finally exit if the rpm is not found else copy
      if (defined($path))
      {
          # Get the latest version of the file in the first location found
          #my $rpmfile = NodeUtils->runcmd("$::LS $path/$rpm_pre_file | $::HEAD -1", -1);
          my  $rpmfile = InstallUtils->getRecentVersionRpm($path, $rpm_pre_file);
          chomp $rpmfile;
          my $rpmfile_basename;
          ($rpmfile_basename = $rpmfile) =~ s:^.*/::g;

          &copyRpm($rpmfile_basename, $path, $::INSTALLDIR_CSMRPM);
       }
       else
       {
            NodeUtils->message('E1', 'EMsgCANT_FIND', $rpm_pre, join(':',@::PKGPATH));
       }

    }
  }
  else
  {
     NodeUtils->message('E2', 'EMsgINVALID_OSTYPE');
  }
}

sub copy_distro_rpms
{
 if ($::ATTRS{'InstallOSName'} eq "Linux")
 {
    my $distro          = $::DISTRO;
    my $destination     = $::INSTALLDIR_OS_NAME_RPMS;
    my ($disk, $cmd, $rc);
    my @notfound;
    my ($my_prereq, $prereq, $path, $dir, $rpm_pre_file);

    NodeUtils->message('I', 'IMsgCOPYING_LINUX_RPMS');


    # First try to get the distro rpms out of the pkg path (which may
    # include the CSM CD).  This allows us to put newer versions of some
    # distro rpms on our media if we need to.
    # Note:  DISTRO_PREREQS is a hash of array references, thus the
    #        funny syntax below.
    my (@DISTRO_PKGPATH) = @::PKGPATH;
    map {s|$|/$::DISTRO_RPMDIR{$distro}|} @DISTRO_PKGPATH;

    foreach $prereq (@::os_prereq)
      {
            if ($::ATTRS{'InstallPkgArchitecture'} =~ /i?86/)
            {
               $my_prereq="$prereq.i?86.rpm";
               NodeUtils->message('V', 'IMsgSEARCHING_FOR_PREREQ', $prereq);
               $path = InstallUtils->findRpmInPath($my_prereq, @DISTRO_PKGPATH);
            }
            else
            {
               $my_prereq="$prereq.ia64.rpm";
               NodeUtils->message('V', 'IMsgSEARCHING_FOR_PREREQ', $prereq);
               $path = InstallUtils->findRpmInPath($my_prereq, @DISTRO_PKGPATH);
               if (!($path))
               {
                 $my_prereq="$prereq.i?86.rpm";
                 NodeUtils->message('V', 'IMsgSEARCHING_FOR_PREREQ', $prereq);
                 $path = InstallUtils->findRpmInPath($my_prereq, @DISTRO_PKGPATH);
               }
            }
            if (!($path))
            {
              $my_prereq="$prereq.noarch.rpm";
              $path = InstallUtils->findRpmInPath($my_prereq, @DISTRO_PKGPATH);
            }
            if (defined($path))
            {
                # Get the latest version of the file in the first location found
                if ($::PLTFRM eq "Linux")
                {
                   #$rpm_pre_file = NodeUtils->runcmd("$::LS -vr $path/$my_prereq | $::HEAD -1", -1);
                   $rpm_pre_file = InstallUtils->getRecentVersionRpm($path, $my_prereq);
                }
                else
                {
                   #$rpm_pre_file = NodeUtils->runcmd("$::LS $path/$my_prereq | $::HEAD -1", -1);
                   $rpm_pre_file = InstallUtils->getRecentVersionRpm($path, $my_prereq);
                }
                chomp $rpm_pre_file;
                my $rpmfile_basename;
                ($rpmfile_basename = $rpm_pre_file) =~ s:^.*/::g;

                &copyRpm($rpmfile_basename, $path, $destination);
            }
            else { push @notfound, $prereq; }
      }

    if (!scalar(@notfound)) { return; }     # found them all

    # Copy RPMs from Redhat/TurboLinux distribution CD-ROM(s)
    # to /tftpboot/<distro_rpmdir> (i.e. /tftpboot/rh71)
    $cmd = "umount $::MNTCDROM > /dev/null 2>&1";
    &run_cmd($cmd, "W", "ignore_errors");

    foreach $disk (split (/\s/, $::DISTRO_DISKLIST{$distro}))
    {
        NodeUtils->message('I', 'IMsgINSERT_DISK', $::DISTRO_NAME{$distro}, $disk);
        NodeUtils->message('P', 'IMsgPRESS_ENTER');

        my $junk = getc;

        $cmd = "mount $::MNTCDROM";
        &run_cmd($cmd, "W");
        foreach $prereq (@notfound)
          {
                if ($::ATTRS{'InstallPkgArchitecture'} =~ /i?86/)
                {
                  $my_prereq="$prereq.i?86.rpm";
                  if (!length($prereq)) { next; }    # already found that one
                  NodeUtils->message('V', 'IMsgSEARCHING_FOR_PREREQ_ON_CD', $prereq, $disk);
                  $dir = "$::MNTCDROM/$::DISTRO_RPMDIR{$distro}";
                  $path = InstallUtils->findRpmInPath($my_prereq, $dir);
                }
                else
                {
                  $my_prereq="$prereq.ia64.rpm";
                  if (!length($prereq)) { next; }    # already found that one
                  NodeUtils->message('V', 'IMsgSEARCHING_FOR_PREREQ_ON_CD', $prereq, $disk);
                  $dir = "$::MNTCDROM/$::DISTRO_RPMDIR{$distro}";
                  $path = InstallUtils->findRpmInPath($my_prereq, $dir);
                  if (!($path))
                  {
                    $my_prereq="$prereq.i?86.rpm";
                    if (!length($prereq)) { next; }    # already found that one
                    NodeUtils->message('V', 'IMsgSEARCHING_FOR_PREREQ_ON_CD', $prereq, $disk);
                    $path = InstallUtils->findRpmInPath($my_prereq, $dir);
                  }
                }
                if (!($path))
                {
                  $my_prereq="$prereq.noarch.rpm";
                  $path = InstallUtils->findRpmInPath($my_prereq, $dir);
                }
                if (defined($path))
                  {
                        # Get the latest version of the file in the first location found
                        if ($::PLTFRM eq "Linux")
                        {
                           #$rpm_pre_file = NodeUtils->runcmd("$::LS -vr $path/$my_prereq | $::HEAD -1", -1);
                           $rpm_pre_file = InstallUtils->getRecentVersionRpm($path, $my_prereq);
                        }
                        else
                        {
                           #$rpm_pre_file = NodeUtils->runcmd("$::LS $path/$my_prereq | $::HEAD -1", -1);
                           $rpm_pre_file = InstallUtils->getRecentVersionRpm($path, $my_prereq);
                        }
                        chomp $rpm_pre_file;
                        my $rpmfile_basename;
                        ($rpmfile_basename = $rpm_pre_file) =~ s:^.*/::g;

                        &copyRpm($rpmfile_basename, $path, $destination);
                        $prereq = '';         # so we do not search for it on the next cd
                  }
          }

        # See if there were any we did not find
        my $nf = join(' ', @notfound);      # this eliminates the ones we blanked out
        @notfound = split(' ', $nf);
        if (!scalar(@notfound)) { last; }    # do not need to go to the next cd

        #$cmd = "$::COPY --update $::MNTCDROM/$::DISTRO_RPMDIR{$distro}/* $destination";
        #&run_cmd($cmd, "W");

        $cmd = "umount $::MNTCDROM > /dev/null 2>&1";
        &run_cmd($cmd, "W");
    }

        if (scalar(@notfound)) { NodeUtils->message('E1', 'EMsgPREREQ_NOT_FOUND', join(', ',@notfound)); }
 }
 elsif ($::ATTRS{'InstallOSName'} eq "AIX")
 {
 }
 else
 {
    NodeUtils->message('E2', 'EMsgINVALID_OSTYPE');
 }
}

# OBSOLETE sub routine .. May be for feature use
sub extractcsmbin
{
 NodeUtils->message('I', 'IMsgExtractingCsmBin');
 if ($::ATTRS{'InstallOSName'} eq "AIX")
 {
   my @my_temp_bin_arry=();
   my $temp_bin_file="";
   my ($ret_code,$temp_dir);
   $temp_dir=`pwd`;
   chomp ($temp_dir);
   chdir($::INSTALLDIR_CSMINSTLP);
   # Extract file from csm.core
   foreach $temp_bin_file (@::csmbin_core)
   {
     push(@my_temp_bin_arry, "./".$temp_bin_file) 
   } 
   $temp_bin_file="";
   foreach $temp_bin_file (@my_temp_bin_arry)
   {
     $ret_code=NodeUtils->runcmd("$::RESTORE -xqf $::INSTALLDIR_CSMINSTLP/csm.core $temp_bin_file",-1);
     if ($::RUNCMD_RC !=0)
     {
        NodeUtils->message('W','EMsgCannotExtract',$temp_bin_file,"$::INSTALLDIR_CSMINSTLP/csm.core");
     }
   }
   # Extract file from csm.server
   $temp_bin_file="";
   @my_temp_bin_arry=();
   foreach $temp_bin_file (@::csmbin_server)
   {
     push(@my_temp_bin_arry, "./".$temp_bin_file)
   }
   $temp_bin_file="";
   foreach $temp_bin_file (@my_temp_bin_arry)
   {
     $ret_code=NodeUtils->runcmd("$::RESTORE -xqf $::INSTALLDIR_CSMINSTLP/csm.server $temp_bin_file",-1);
     if ($::RUNCMD_RC !=0)
     {
        NodeUtils->message('W','EMsgCannotExtract',$temp_bin_file,"$::INSTALLDIR_CSMINSTLP/csm.server");
     }
   }
   chdir("$temp_dir");
 }
 elsif ($::ATTRS{'InstallOSName'} eq "Linux")
 {
   my $temp_bin_file="";
   my ($ret_code, $temp_rpm, $temp_dir);
   $temp_dir=`pwd`;
   chomp ($temp_dir);
   chdir($::INSTALLDIR_CSMINSTLP);
   # Extract file from csm.core
   $temp_bin_file="";
   foreach $temp_bin_file (@::csmbin_core)
   {
     $ret_code=NodeUtils->runcmd("$::RPM2CPIO $::INSTALLDIR_CSMPKG/csm.core*.rpm | $::CPIO -ivd $temp_bin_file",-1);
     if ($::RUNCMD_RC !=0)
     {
        NodeUtils->message('W','EMsgCannotExtract',$temp_bin_file,"$::INSTALLDIR_CSMINSTLP/csm.core*rpm");
     }
   }
   # Extract file from csm.server
   $temp_bin_file="";
   $temp_bin_file="";
   foreach $temp_bin_file (@::csmbin_server)
   {
     $ret_code=NodeUtils->runcmd("$::RPM2CPIO $::INSTALLDIR_CSMPKG/csm.server*.rpm | $::CPIO -ivd $temp_bin_file",-1);
     if ($::RUNCMD_RC !=0)
     {
        NodeUtils->message('W','EMsgCannotExtract',$temp_bin_file,"$::INSTALLDIR_CSMINSTLP/csm.server*rpm");
     }
   }
   # Extract file from atftp package
   $temp_bin_file="";
   $temp_bin_file="";
   foreach $temp_bin_file (@::csmbin_opensrc)
   {
     $ret_code=NodeUtils->runcmd("$::RPM2CPIO $::INSTALLDIR_CSMPKG/atftp*.rpm | $::CPIO -ivd $temp_bin_file",-1);
     if ($::RUNCMD_RC !=0)
     {
        NodeUtils->message('W','EMsgCannotExtract',$temp_bin_file,"$::INSTALLDIR_CSMINSTLP/atftp*rpm");
     }
   }
   chdir($temp_dir);
 }
 else
 {
    NodeUtils->message('E2', 'EMsgINVALID_OSTYPE');
 }
}

# OBSOLETE sub routine .. May be for feature use
sub copy_csmbin
{
 NodeUtils->message('I', 'IMsgCOPYING_CSMBINARIES');
 if ($::ATTRS{'InstallOSName'} eq "AIX")
 {
  my @temp_copy_arry=();
  @temp_copy_arry=(@::csmbin_core, @::csmbin_server, @::csmbin_opensrc);
  my $temp_bin_file="";
  foreach $temp_bin_file (@temp_copy_arry)
  {
    NodeUtils->runcmd("$::COPY $::INSTALLDIR_CSMINSTLP/$temp_bin_file $::INSTALLDIR_CSMVR",-1);
    if ($::RUNCMD_RC !=0)
    {
       NodeUtils->message('W','EMsgCANT_COPY',"$::INSTALLDIR_CSMINSTLP/$temp_bin_file",$::INSTALLDIR_CSMVR); 
    }
  }
 }
 elsif ($::ATTRS{'InstallOSName'} eq "Linux")
 {
  my @temp_copy_arry=();
  @temp_copy_arry=(@::csmbin_core, @::csmbin_server, @::csmbin_opensrc);
  my $temp_bin_file="";
  foreach $temp_bin_file (@temp_copy_arry)
  {
    NodeUtils->runcmd("$::COPY $::INSTALLDIR_CSMINSTLP/$temp_bin_file $::INSTALLDIR_CSMVR",-1);
    if ($::RUNCMD_RC !=0)
    {
       NodeUtils->message('W','EMsgCANT_COPY',"$::INSTALLDIR_CSMINSTLP/$temp_bin_file",$::INSTALLDIR_CSMVR); 
    }
  }
 }
 else
 {
    NodeUtils->message('E2', 'EMsgINVALID_OSTYPE');
 }
}

###########################################
#
#    Main
#
###########################################

# Check the arguments
&getArgs;

# get the packege list that need to copies
&getPackageList;

#Create the necessary directory structure
&create_directory_structure;

#Copy the csm, rsct , opensrc  and os pre requisite packages
&copy_csm;
&copy_opensrc_prereqs;
&copy_distro_rpms;

#Extract the csm binary version specific  files
#&extractcsmbin;

#Copy the extarcted files to tyhe csminstall/csm/<csmVersion> directory
#&copy_csmbin;

